﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using jSLApp.Client.Forms;
using jSLApp.Client.MainService;
using jSLApp.Client.Security;
using jSLApp.Client.Workflow;
using jSLCore.Client.Presentation;
using jSLCore.Client.Presentation.ApplicationContainer;
using jSLCore.Client.Presentation.Authorization;
using jSLCore.Client.Presentation.Authorization.Managment;
using jSLCore.Client.Presentation.BaseControl;
using jSLCore.Client.Presentation.BaseControl.DialogMessage;
using jSLCore.Client.Presentation.Common;
using jSLCore.Client.Presentation.jBinding.BaseValidationRules;
using jSLCore.Client.Utility;
using jSLCore.Utility.Extensions;
using Chat = jSLApp.Client.Forms.Chat;

namespace jSLApp.Client.ApplicationBase
{
    public partial class MainContentContainer : ContentContainerBase, ISilentDoWork
    {
        public MainContentContainer()
        {
            InitializeComponent();

            Loaded += (o, eventArgs) =>
                          {
                                 ParentApplicationContainer.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(@"/jSLApp.Client;component/Resources/UndergroundStyle.xaml", UriKind.RelativeOrAbsolute) });
                             // CheckChat();
                                 jSecurity.SecurityChanged += (sender, args) =>
                                 {
                                     UpdateSecurity();
                                 };
                              // UpdateSecurity(); crash here, cause child form is not yet loaded and dont know what ParentApplicationContainer is
                          };

            _chatController = new ChatController(this);
        }

        private void UpdateSecurity()
        {
            if(jSecurity.IsAuthorized)
            {
                picPanel.Visibility = Visibility.Visible;
                var dataControl = CurrentContent as DataControl;
                if (dataControl != null) dataControl.LoadInitialData();
                reg.Visibility = Visibility.Collapsed;
                DoWork(true,(o, eventArgs) => Communication.Proxy.Visit(),null);
            }
            else
            {
                picPanel.Visibility = Visibility.Collapsed;
                
                if ((!(CurrentContent is MusicList) && !((CurrentContent is MusicDetail))))
                    if(ParentApplicationContainer!=null)
                        GotoList();
                else
                {
                    var dataControl = CurrentContent as DataControl;
                    if (dataControl != null) dataControl.LoadInitialData();
                }
                reg.Visibility = Visibility.Visible;
            }
        }

        public void GotoForum()
       {
           if(!jSecurity.IsAuthorized)
           {
               ErrorBox.ShowDialog("Неавторизованные пользователи не могут просматривать форум");
               return;
           }

           ParentApplicationContainer.CloseAllDialogs();
           var page = new Forum();
           this.ShowPage(page,false);
       }

        public void SendEMail(string toLogin)
        {
            var dlg = new jAskForStringBox("Текст письма:",string.Empty,true);
            dlg.ShowDialog(delegate(object sender, object data)
                               {
                                   var message = data as string;

                                   if(!string.IsNullOrEmpty(message))
                                   {
                                       DoWork("Отправка письма", (o, args) =>
                                                                     {
                                                                         Communication.Proxy.SendMailToUser(args.String,(string) args.Params[1]);
                                                                     }, (sender1, eventArgs) =>
                                                                                       {
                                                                                           if(eventArgs.Error==null)
                                                                                           {
                                                                                               InfoBox.ShowDialog("Письмо отправлено. Пользователь сможет ответить непосредственно на ваш e-mail.");
                                                                                           }
                                                                                       },toLogin,message);
                                   }
                               },this);
        }

        public override void GotoIndexedPage(string key, string value)
        {
            switch (key)
            {
                case PageNames.ArticleDetail:
                    try{
                    GotoArticle(int.Parse(value));
                    }

                    catch (FormatException) { }
                    catch (OverflowException) { }
                    catch (ArgumentNullException) { }
                    break;
                case PageNames.UnsubsribeAll:
                    try
                    {
                    DoWork("Отписка от всех событий",(o1, workEventArgs) => Communication.Proxy.UnSubsribeAll(workEventArgs.Guid),(sender2, completedEventArgs) =>
                                                                                    {
                                                                                        if (completedEventArgs.Error == null)
                                                                                        {
                                                                                            InfoBox.ShowDialog(
                                                                                                "Вы успешно отписались от всех событий сайта");
                                                                                        }
                                                                                    },Guid.Parse(value));
                    }
                    catch (FormatException) { }
                    catch (OverflowException) { }
                    catch (ArgumentNullException) { }
                    break;
                case PageNames.TopicDetail:
                    try
                    {
                        GotoTopic(int.Parse(value));
                    }
                    catch (FormatException) { }
                    catch (OverflowException) { }
                    catch (ArgumentNullException) { }
                    break;
                case PageNames.MusicDetail:
                    try
                    {
                        GotoSong(int.Parse(value), true);
                    }

                    catch (FormatException) { }
                    catch (OverflowException) { }
                    catch (ArgumentNullException) { }
                    break;
                case PageNames.EmailVerificationCode:
                    var verCode = value;
                Guid rescode;
                if(Guid.TryParse(verCode,out rescode))
                {
                    DoWork("Подтверждение регистрации",(sender, args) => Communication.Proxy.SubmitEMail(args.Guid),(o, eventArgs) =>
                                                                 {
                                                                     if(eventArgs.Error==null)
                                                                     {
                                                                         InfoBox.ShowDialog("Ваш адрес электронной почты подтвержден. Ваш аккаунт разблокирован.Окно будет закрыто автоматически.");
                                                                         ReloadWithOutParameters();
                                                                     }
                                                                 },rescode);
                }
                else
                {
                 ErrorBox.ShowDialog("Неверный код подтверждения");   
                }
                    break;

                case PageNames.PwdChangeVerificationCode:
                     var chCode = value;
                var reschcode = new Guid();
                if (Guid.TryParse(chCode, out rescode))
                {
                    var dlg = new jAskForStringBox("Укажите новый пароль:","",false);
                    dlg.ShowDialog(delegate(object sender, object data)
                                       {
                                           var str = data as string;
                                           if(!string.IsNullOrEmpty(str))
                                           {
                                               DoWork("Смена пароля", (o, args) => Communication.Proxy.SubmitPasswordChange(
                                                   args.Guid, (string) args.Params[1]), (sender1, eventArgs) =>
                                                                                            {
                                                                                                if(eventArgs.Error==null)
                                                                                                {
                                                                                                    InfoBox.ShowDialog("Пароль изменен. Окно будет закрыто автоматически");
                                                                                                    ReloadWithOutParameters();
                                                                                                }
                                                                                            }, reschcode,str);
                                           }
                                           else
                                           {
                                               ErrorBox.ShowDialog("Необходимо указать пароль. Попробуйте еще раз.");
                                           }
                                       },this);
                }
                else
                {
                    ErrorBox.ShowDialog("Неверный код подтверждения");
                }
                    break;
            }
        }


        private void ReloadWithOutParameters()
        {
            SLWPFSelector.ReloadHtmlPage(this);
        }

        

        public void GotoSong(int id,bool autoPlay = false)
        {
            ParentApplicationContainer.CloseAllDialogs();
            ShowPage(new MusicDetail(id, autoPlay), false);
        }

        public void DownloadMusic(int musicId)
        {
            var dlg = new SaveFileDialog();
            dlg.Filter = @"Файл музыки|*.mp3";
            if (dlg.ShowDialog().GetValueOrDefault(false))
            {
                DoWork("Загрузка файла", (o, args) =>
                {
                    args.Result = Communication.Proxy.GetMusicFile(args.Int);
                }, (sender1, eventArgs) =>
                {
                    if (eventArgs.Error == null)
                    {
                        var stream = dlg.OpenFile();
                        var buffer = (byte[])eventArgs.Result;
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Close();
                        InfoBox.ShowDialog("Файл успешно загружен");
                    }
                }, musicId);
            }
        }

        public void PlayMusic(string fileName, string whatsPlay, int musicId)
        {
            nowPlayingText.Content = whatsPlay;
            nowPlayingText.Tag = musicId;
            musicPlayer.Play(new Uri(UIHelper.GetCurrentWebHostAddress() + fileName));
            //encresing count
            DoWork(true,(sender, args) =>
                            {
                                Communication.Proxy.EncreaseListenCount(args.Int);
                            },(o, eventArgs) =>
                                                  {
                                                      
                                                  },musicId);
        }

        public void GotoList()
        {
            ParentApplicationContainer.CloseAllDialogs();

            ShowPage(new MusicList(),false);
        }

        private BaseControl LastPage;
        public ChatController _chatController;

        public override void ShowPage(BaseControl control, bool asDialog)
        {
            LastPage = CurrentContent;
            base.ShowPage(control, asDialog);
            BindPage(control);
        }

        private void BindPage(BaseControl control)
        {
         /*   imgHeader.Header = control.Title;
            imgHeader.Image = control.Icon;*/
        }



        protected override BaseControl GetDefaultPage()
        {
            return new MusicList();
        }

        protected override ContentPresenter GetMainContentPresenter()
        {
            return mainContent;
        }

        protected override ContentPresenter GetOkCancelControlContentPresenter()
        {
            return okCancelPresenter;
        }

        private void add_Clicked(object sender, RoutedEventArgs e)
        {
            var dlg = new AddMusic();
            dlg.ShowDialog(delegate(object o, object data)
                               {
                                   GotoSong((int) data,false);
                               }, this);
            /*  var dlg = new OpenFileDialog();
            dlg.ShowDialog();
            var fileStream = dlg.File.OpenRead();

            var bs = new byte[fileStream.Length];
            fileStream.Read(bs, 0, bs.Length);
            fileStream.Close();
            DoWork("Закачка файла",(o, args) =>
                                       {
                                           Communication.Proxy.LoadFile((byte[]) args.Argument);
                                         //  Communication.Proxy.LoadFile(new byte[]{1,2,3,4});
                                       },(sender1, eventArgs) =>
                                                        {
                                                            if(eventArgs.Error==null)
                                                            {
                                                                InfoBox.ShowDialog("Файл успешно закачан.");
                                                            }
                                                        },bs);*/
        }

        private void gotoList_Clicked(object sender, RoutedEventArgs e)
        {
            GotoList();
        }

      

        private void GoSong(object sender, RoutedEventArgs e)
        {
            ParentApplicationContainer.CloseAllDialogs();

            var element = (FrameworkElement)sender;

            GotoSong((int) element.Tag,false);
        }

        

        private void gotoUsers_Clicked(object sender, RoutedEventArgs e)
        {
            ShowPage(new UserList(), false);
        }

        private void gotoManagment_Clicked(object sender, RoutedEventArgs e)
        {
            var dlg = new ManagmentPanel();
            NavigateTo(dlg);
        }

        public static MainContentContainer Current
        {
            get { return (MainContentContainer) ApplicationContainer.CurrentContentContainer; }
        }


        private void gotoEditRoles_Clicked(object sender, RoutedEventArgs e)
        {
            var dlg = new AdministratorAccessRoles();
            dlg.ShowDialog(this);
        }

        private void registr(object sender, RoutedEventArgs e)
        {
            new Registration().ShowDialog(this);
        }

        private void gotoAccaunt_Clicked(object sender, RoutedEventArgs e)
        {
            GotoUserAbout(jSecurity.Login);
        }

        public void GotoUserAbout(string login)
        {
            ParentApplicationContainer.CloseAllDialogs();
            var dlg = new UserAbout(login);
            ShowPage(dlg, false);
        }

        private void gotoMessages_Clicked(object sender, RoutedEventArgs e)
        {
            var dlg = new MessageList(jSecurity.Login);
            dlg.ShowDialog(this);
        }

        private void gotoArticles_Clicked(object sender, RoutedEventArgs e)
        {
            GotoArticles();
        }

        public void GotoArticles()
        {
            var dlg = new ArticleList();
            ShowPage(dlg,false);
        }

        public void GotoArticle(int articleId)
        {
            ParentApplicationContainer.CloseAllDialogs();
            var dlg = new ArticleDetail(articleId);
            ShowPage(dlg,false);
        }


        private void gotoForum_Clicked(object sender, RoutedEventArgs e)
        {
            if(jSecurity.IsAuthorized)
                GotoForum();
            else
            {
                ErrorBox.ShowDialog("Форум доступен только зарегистрированным пользователям");
            }
        }

        public void CreateTopic()
        {
            var dlg = new jAskForStringBox("Укажите название топика",String.Empty, false);
            dlg.ShowDialog(delegate(object sender, object data)
                               {
                                   var str = (string)data;
                                   var comment = new NewComment(){IsRatingEnabled = false};
                                   comment.ShowDialog(delegate(object o, object data1)
                                                          {
                                                              DoWork("Создание топика...",(sender1, args) =>
                                                                                              {
                                                                                                  args.Result =
                                                                                                      Communication.
                                                                                                          Proxy.
                                                                                                          CreateTopic(
                                                                                                              args.
                                                                                                                  String,
                                                                                                              (string)
                                                                                                              args.
                                                                                                                  Params
                                                                                                                  [1]);
                                                                                              },(o1, eventArgs) =>
                                                                                                                     {
                                                                                                                         if(eventArgs.Error==null)
                                                                                                                         {
                                                                                                                             GotoTopic((int) eventArgs.Result);
                                                                                                                         }
                                                                                                                     },str,data1);
                                                          }, this);
                               },this);
        }

        public void GotoTopic(int commentableId)
        {
            ParentApplicationContainer.CloseAllDialogs();

            var dlg = new TopicDetail(commentableId);
            ShowPage(dlg,false);
        }

        public void GoCommentable(CommentableType commentableType, int id)
        {
            switch (commentableType)
            {
                case CommentableType.Music:
                    MainContentContainer.Current.GotoSong(id);
                    break;
                case CommentableType.NewsAcrtible:
                    MainContentContainer.Current.GotoArticle(id);
                    break;
                case CommentableType.Topic:
                    MainContentContainer.Current.GotoTopic(id);
                    break;
            }
        }

        private void goBack_Clicked(object sender, RoutedEventArgs e)
        {
            if(LastPage!=null)ShowPage(LastPage,false);
        }

        private void gotoLogs_Clicked(object sender, RoutedEventArgs e)
        {
            var dlg = new LogList();
            ShowPage(dlg,false);
        }

        private void GotoChat()
        {
            ParentApplicationContainer.CloseAllDialogs();

            var chat = new Chat {grid = {ItemsSource = _chatController.ChatItems}};
            chat.ShowDialog(this);
        }

        public new void DoWork(bool dontShowSplash, MutliWorkEventHandler doWorkEventHandler, System.ComponentModel.RunWorkerCompletedEventHandler runWorkerCompletedEventHandler, params object[] initialData)
        {
            base.DoWork(null,doWorkEventHandler, runWorkerCompletedEventHandler,initialData);
        }

        public void ShowNewMessages(IEnumerable<MainService.Chat> newMessages)
        {
            if (ChatController.AutoUpdate)
                if (!(ParentApplicationContainer.Dialog is Chat))
            {
                chatGrid.ItemsSource = newMessages;
                PlayMessage.Begin();
            }
        }

        private void gotoChat_Clicked(object sender, RoutedEventArgs e)
        {
            GotoChat();
        }


        private void chat_Clicked(object sender, MouseButtonEventArgs e)
        {
            GotoChat();
        }

        private void righterFeedback_Clicked(object sender, RoutedEventArgs e)
        {
            var dlg = new jAskForStringBox("Введите текст сообщения:","",true,new jNotEmptyStringRule(),null);
            dlg.ShowDialog((o, data) =>
                               {
                                   var str = (string) data;
                                   DoWork("Отправка письма",(sender1, args) => Communication.Proxy.SendMailToUser("jinek",str),(o1, eventArgs) =>
                                                                                       {
                                                                                           if(eventArgs.Error==null)
                                                                                           {
                                                                                               InfoBox.ShowDialog("Письмо отправлено");
                                                                                           }
                                                                                       },str);
                               });
        }
    }
}
